package com.gzhryc.shared_device.oem.h5.mng.controllers.market;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

import com.gzhryc.common.ClassTools;
import com.gzhryc.common.DateTools;
import com.gzhryc.common.StringTools;
import com.gzhryc.common.data.dto.AjaxResult;
import com.gzhryc.common.data.dto.ListResult;
import com.gzhryc.common.exceptions.LogicException;
import com.gzhryc.common.json.JsonTools;
import com.gzhryc.common.logging.Logger;
import com.gzhryc.net_marketing.cloud.MarketConstants;
import com.gzhryc.net_marketing.cloud.business.dao.db.PayGoodsOrder;
import com.gzhryc.net_marketing.cloud.business.dao.db.PayGoodsOrderLog;
import com.gzhryc.net_marketing.cloud.business.dao.enums.PayGoodsOrderEnum;
import com.gzhryc.net_marketing.cloud.business.services.PayGoodsOrderLogService;
import com.gzhryc.net_marketing.cloud.business.services.PayGoodsOrderService;
import com.gzhryc.net_marketing.cloud.business.services.dto.PayGoodsOrderSearch;
import com.gzhryc.net_marketing.cloud.business.services.models.PayGoodsOrderLogItem;
import com.gzhryc.net_marketing.core.enums.EGoodsClassify;
import com.gzhryc.net_marketing.core.enums.EReceiveGoodsType;
import com.gzhryc.net_marketing.core.enums.GoodsOrderEnum;
import com.gzhryc.pay.adaptation.weixin.WXPayNormalPayService;
import com.gzhryc.pay.adaptation.weixin.msg.normal.WXPayNormalOrderResponse;
import com.gzhryc.servlet.DtoConstants;
import com.gzhryc.servlet.WebUtils;
import com.gzhryc.servlet.annotation.Route;
import com.gzhryc.shared_device.base.enums.EOperatorType;
import com.gzhryc.shared_device.base.enums.EPayType;
import com.gzhryc.shared_device.base.models.OperateInfo;
import com.gzhryc.shared_device.common.payment.dao.db.WXPayOrder;
import com.gzhryc.shared_device.common.payment.dao.db.WXRefundOrder;
import com.gzhryc.shared_device.common.payment.services.WXPayOrderService;
import com.gzhryc.shared_device.common.payment.services.WXRefundOrderService;
import com.gzhryc.shared_device.oem.code.PayServiceFactory;
import com.gzhryc.shared_device.oem.code.business.EBusinessType;
import com.gzhryc.shared_device.oem.h5.mng.WebConstants;
import com.gzhryc.system.SysConstants;
import com.gzhryc.system.dao.db.Manager;

/**
 * 订单管理
 */
public class GoodsOrderController {

    static Logger log = Logger.getLogger(GoodsOrderController.class);

    @Route(value = { "/market/project/order/list.html" })
    public String list(HttpServletRequest request) {
        request.setAttribute("businessTypeList", PayGoodsOrderEnum.BusinessType.values());
        request.setAttribute("stateList", GoodsOrderEnum.State.values());
        request.setAttribute("supplyStateList", GoodsOrderEnum.SupplyState.values());
        request.setAttribute("payTypeList", EPayType.values());
        return "/market/order/list.html";
    }

    @Route(value = "/market/project/order/list.data")
    public ListResult<PayGoodsOrder> listData(HttpServletRequest request) {
        ListResult<PayGoodsOrder> result = new ListResult<PayGoodsOrder>(DtoConstants.SUCCESS);

        PayGoodsOrderSearch search = WebUtils.getParameter(request, PayGoodsOrderSearch.class);
        Integer pageNo = WebUtils.getInteger(request, "page", 1);
        Integer pageLimit = WebUtils.getInteger(request, "limit", WebConstants.PAGE_LIMIT);

        result.getBody().setTotal(PayGoodsOrderService.self(MarketConstants.JDBC_KEY).countBySearch(search));
        result.getBody().setData(PayGoodsOrderService.self(MarketConstants.JDBC_KEY).findBySearch(search, pageNo, pageLimit));

        if (result.getBody().getTotal() == 0) {
            result.setCode(DtoConstants.NULL_DATA, "暂无数据");
        }

        return result;
    }

    @Route(value = { "/market/project/order/operate.html" })
    public String operate(HttpServletRequest request, HttpServletResponse response) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        if(StringTools.isNotBlank(tradeNo)){
            PayGoodsOrder goodsOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getJoinByTradeNo(tradeNo);
            WebUtils.setAttribute(request,goodsOrder);

            List<WXPayOrder> payOrderList = WXPayOrderService.self(goodsOrder.getCreateDate()).findByBusinessTradeNo(tradeNo);
            request.setAttribute("payOrderList",payOrderList);

            List<WXRefundOrder> refundOrderList = WXRefundOrderService.self(goodsOrder.getCreateDate()).findByBusinessTradeNo(tradeNo);
            request.setAttribute("refundOrderList",refundOrderList);
        }
        return "/market/order/operate.html";
    }

    @Route(value = { "/market/project/order/operate/syn.do" })
    public AjaxResult doSyn(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "同步订单状态失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
        if (StringTools.isNotBlank(tradeNo)) {
            PayGoodsOrder goodsOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getJoinByTradeNo(tradeNo);
            if (goodsOrder != null) {
            	 if (EPayType.WXPay.index().equals(goodsOrder.getPayType())) {
            		 WXPayOrder payOrder = WXPayOrderService.self(goodsOrder.getCreateDate()).getLastByBusinessTradeNo(goodsOrder.getTradeNo());
            		 if(payOrder != null){
                       WXPayNormalPayService payService = PayServiceFactory.self().getWXPayNormalPayService(payOrder.getAppId()
                    		   ,EBusinessType.MARKET.index());
                       if(payService != null){
                           //使用本系统订单号
                           WXPayNormalOrderResponse externalPayOrder = payService.queryByTradeNo(payOrder.getTradeNo());
                           try {
                               payOrder = WXPayOrderService.self(goodsOrder.getCreateDate()).synExternalPayOrder(payOrder,externalPayOrder);
                                if(payOrder != null){
                                    OperateInfo operateInfo = new OperateInfo();
                                    operateInfo.setProgramType(WebConstants.PROGRAM_TYPE);
                                    operateInfo.setOperatorType(EOperatorType.Manager.index());
                                    operateInfo.setOperator(manager.getFullName());

                                    PayGoodsOrderService.self(MarketConstants.JDBC_KEY).payResult(payOrder,operateInfo);
                                    result.setCode(DtoConstants.SUCCESS, null);
                                }
                           } catch (LogicException e) {
                               result.setMsg(e.getMessage());
                           }
                       }else{
                           result.setMsg("未找到支付服务");
                       }
                    }
                }else{
                    result.setMsg("未找到支付订单");
                }
            }
        }
        return result;
    }

    /**
     * 触发退款
     * @param request
     * @param session
     * @return
     */
    @Route(value = { "/market/project/order/operate/refund.do" })
    public AjaxResult doRefund(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "退款失败");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
        if(StringTools.isNotBlank(tradeNo)){
            PayGoodsOrder goodsOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getJoinByTradeNo(tradeNo);
            if(goodsOrder != null){
                OperateInfo operateInfo = new OperateInfo();
                operateInfo.setProgramType(WebConstants.PROGRAM_TYPE);
                operateInfo.setOperatorType(EOperatorType.Manager.index());
                operateInfo.setOperator(manager.getFullName());
                
                if (EPayType.WXPay.index().equals(goodsOrder.getPayType())) {
                	WXPayOrder payOrder = WXPayOrderService.self(goodsOrder.getCreateDate()).getLastByBusinessTradeNo(goodsOrder.getTradeNo());
           		 	if(payOrder != null){
	                    WXPayNormalPayService payService = PayServiceFactory.self().getWXPayNormalPayService(payOrder.getAppId()
		                 		   ,EBusinessType.MARKET.index());
		                try {
		                    if(PayGoodsOrderService.self(MarketConstants.JDBC_KEY).toRefundOrder(goodsOrder,payService,operateInfo)){
		                        result.setCode(DtoConstants.SUCCESS, null);
		                    }
		                } catch (LogicException e) {
		                    result.setMsg(e.getMessage());
		                }
           		 	}
                }
            }else{
                result.setMsg("未找到订单信息");
            }
        }else{
            result.setMsg("参数错误");
        }
        return result;
    }

    @Route(value = { "/market/project/order/operate/confirm.do" })
    public AjaxResult doOrderConfirm(HttpServletRequest request,HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR,"确认订单失败");
        String tradeNo = WebUtils.getString(request,"tradeNo");
        Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
        try {
            OperateInfo operateInfo = new OperateInfo();
            operateInfo.setProgramType(WebConstants.PROGRAM_TYPE);
            operateInfo.setOperatorType(EOperatorType.Manager.index());
            operateInfo.setOperator(manager.getFullName());

            PayGoodsOrder goodsOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getByTradeNo(tradeNo);
            if(PayGoodsOrderService.self(MarketConstants.JDBC_KEY).confirmGoods(goodsOrder,operateInfo)) {
                result.setCode(DtoConstants.SUCCESS, null);
            }
        } catch (LogicException e) {
            result.setMsg(e.getMessage());
        }
        return result;
    }

    // === 物流信息

    @Route(value = { "/market/project/order/operate/logistics/add.html" })
    public String addLogistics(HttpServletRequest request) {
        String tradeNo = WebUtils.getString(request,"tradeNo");
        PayGoodsOrder simpleTeamPayOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getByTradeNo(tradeNo);
        if(simpleTeamPayOrder != null){
            WebUtils.setAttribute(request,simpleTeamPayOrder);
            if(EGoodsClassify.Fictitious.index().equals(simpleTeamPayOrder.getClassify())) {
               //return "/business/order/fictitious.html";
            }
        }
        return "/market/order/logistics.html";
    }

    @Route(value = { "/market/project/order/operate/logistics/add.do" })
    public AjaxResult doAddLogistics(HttpServletRequest request,HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR,"发货操作失败");
        Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
        String tradeNo = WebUtils.getString(request,"tradeNo");
        String logisticsCompanyId = WebUtils.getString(request,"logisticsCompanyId");
        String logisticsTradeNo = WebUtils.getString(request,"logisticsTradeNo");
        Date logisticsStartDate = WebUtils.getDate(request,"logisticsStartDate");

        OperateInfo operateInfo = new OperateInfo();
        operateInfo.setProgramType(WebConstants.PROGRAM_TYPE);
        operateInfo.setOperatorType(EOperatorType.Manager.index());
        operateInfo.setOperator(manager.getFullName());
        operateInfo.setOperateNote("商家发货");

        try {
            PayGoodsOrder goodsOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getByTradeNo(tradeNo);
            if(PayGoodsOrderService.self(MarketConstants.JDBC_KEY).deliveryGoods(goodsOrder,logisticsCompanyId,null,logisticsTradeNo,logisticsStartDate,operateInfo)) {
                result.setCode(DtoConstants.SUCCESS, null);
            }
        } catch (LogicException e) {
            result.setMsg(e.getMessage());
        }
        return result;
    }

    //收货
    @Route(value = { "/market/project/order/operate/receive.html" })
    public String receiveGoods(HttpServletRequest request) {
        return "/market/order/receive.html";
    }

    @Route(value = { "/market/project/order/operate/receive.do" })
    public AjaxResult doReceiveGoods(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "确认收货失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        Date receiveGoodsDate = WebUtils.getDate(request, "receiveGoodsDate");
        if (StringTools.isNotBlank(tradeNo) && receiveGoodsDate != null) {
            Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
            if (manager == null) {
                result.setCode(DtoConstants.LOGIN_OVERDUE, "登录过期，请重新登录");
                return result;
            }

            OperateInfo operateInfo = new OperateInfo();
            operateInfo.setProgramType(WebConstants.PROGRAM_TYPE);
            operateInfo.setOperatorType(EOperatorType.Manager.index());
            operateInfo.setOperator(manager.getFullName());

            try {
                PayGoodsOrder goodsOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getByTradeNo(tradeNo);
                if(PayGoodsOrderService.self(MarketConstants.JDBC_KEY).receiveGoods(goodsOrder,EReceiveGoodsType.ManagerConfirm.index(),receiveGoodsDate,operateInfo)) {
                    result.setCode(DtoConstants.SUCCESS, null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    @Route(value = { "/market/project/order/operate/evaluate.html" })
    public String evaluateGoods(HttpServletRequest request) {
        return "/market/order/evaluate.html";
    }

    @Route(value = { "/market/project/order/operate/evaluate.do" })
    public AjaxResult doEvaluateGoods(HttpServletRequest request, HttpSession session) {
        AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "评价失败");
        String tradeNo = WebUtils.getString(request, "tradeNo");
        if (StringTools.isNotBlank(tradeNo)) {
            Manager manager = WebUtils.getAttribute(session, SysConstants.SESSION_LOGIN_MANAGER, Manager.class);
            try {
                PayGoodsOrder goodsOrder = PayGoodsOrderService.self(MarketConstants.JDBC_KEY).getByTradeNo(tradeNo);
                if(goodsOrder == null){
                    throw new LogicException("未找到业务订单");
                }

                if(!GoodsOrderEnum.State.WaitEvaluate.index().equals(goodsOrder.getState())){
                    throw new LogicException("业务订单未收货");
                }else{
                    Integer times = DateTools.differenceDay(goodsOrder.getReceiveGoodsDate(),new Date());
                    if(times < 7){
                        throw new LogicException("业务订单收货未到7天");
                    }
                }

                OperateInfo operateInfo = new OperateInfo();
                operateInfo.setProgramType(WebConstants.PROGRAM_TYPE);
                operateInfo.setOperator(manager.getFullName());
                operateInfo.setOperatorType(EOperatorType.Manager.index());
                operateInfo.setOperateNote("默认评价");

                if (PayGoodsOrderService.self(MarketConstants.JDBC_KEY).evaluateGoods(goodsOrder,operateInfo)) {
                    result.setCode(DtoConstants.SUCCESS, null);
                }
            } catch (LogicException e) {
                result.setMsg(e.getMessage());
            }
        }
        return result;
    }

    @Route(value = "/market/project/order/operate/logs/list.data")
    public ListResult<PayGoodsOrderLogItem> operateListData(HttpServletRequest request) {
        ListResult<PayGoodsOrderLogItem> result = new ListResult<>(DtoConstants.SUCCESS);
        String tradeNo = WebUtils.getString(request,"tradeNo");
        if(StringTools.isNotBlank(tradeNo)) {
            PayGoodsOrderLog orderLog = PayGoodsOrderLogService.self(MarketConstants.JDBC_KEY).getOrAddByTradeNo(tradeNo, new Date());
            if (orderLog != null && StringTools.isNotBlank(orderLog.getLogsContent())) {
                List<?> itemList = JsonTools.str2List(orderLog.getLogsContent());
                if (itemList != null && itemList.size() > 0) {
                    result.getBody().setData(new ArrayList<>());
                    for (int i = 0; i < itemList.size(); i++) {
                        PayGoodsOrderLogItem item = ClassTools.copy(new PayGoodsOrderLogItem(), itemList.get(i));
                        result.getBody().getData().add(item);
                    }
                }
            }
        }
        return result;
    }

    @Route(value = { "/market/project/order/del.do" })
	public AjaxResult doDel(HttpServletRequest request) {
		AjaxResult result = new AjaxResult(DtoConstants.EXECUTE_ERROR, "删除商品失败");
		String tradeNo = WebUtils.getString(request, "tradeNo");
		if (StringTools.isNotBlank(tradeNo)) {
			try {
				if (PayGoodsOrderService.self(MarketConstants.JDBC_KEY).deleteByTradeNo(tradeNo)) {
					result.setCode(DtoConstants.SUCCESS, null);
				}
			} catch (LogicException e) {
				result.setMsg(e.getMessage());
			}
		}
		return result;
	}
}
